﻿// ----------------------------------------------------------------------------------------
// Author:                    Magaly Vargas y Joaquín López
// Company:                   ALBALIA INTERACTIVA S.L.
// Assembly version:          1.0.0.0
// Date:                      22/02/2010
// Time:                      12:00
// Solution Name:             OffInvoiceWordAddIn
// Solution Filename:         OffInvoiceWordAddIn
// Solution FullFilename:     C:\Desarrollo\OffInvoiceWordAddIn
// Project Name:              OffInvoiceWordAddIn
// Project Filename:          OffInvoiceWordAddIn.csproj
// Project FullFilename:      C:\Desarrollo\OffInvoiceWordAddIn\OffInvoiceWordAddIn.csproj
// Project Item Name:         CIIGenerator.cs
// Project Item Filename:     CIIGenerator.cs
// Project Item FullFilename: C:\Desarrollo\OffInvoiceWordAddIn\CIIFiles\CIIGenerator.cs
// Project Item Kind:         Código
// Purpose:                   
//Copyright © 2009 - 2010 Albalia Interactiva S.L. Reservados todos los derechos.
// ----------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.ComponentModel;
using System.Xml.Serialization;
using OffInvoiceWordAddIn.CIIFiles;
using Microsoft.Office.Interop.Word;
using System.Globalization;
using OffInvoiceWordAddIn.UBLFiles;

namespace OffInvoiceWordAddIn.CIIFiles
{
    /// <summary>
    /// Clase encargada de formar la factura CII de acuerdo con los datos insertados en la plantilla
    /// Completa la informacion y realiza los calculos y operaciones necesarias para formar la factura CII
    /// </summary>
    /// <remarks>
    /// Algunos datos son opcionales por lo que dependen de ciertos valores que aparezcan en el xml.
    /// Los campos nulos no aprecen en el documento
    /// </remarks>
    class CIIGenerator
    {

        #region "Fields"

        /// <summary>
        /// Referencia al documento activo
        /// </summary>
        Document document = null;

        /// <summary>
        /// Numeración de las tablas del documento
        /// </summary>
        int t2, t3, t4, t5, t6, t7;

        /// <summary>
        /// Array de caracteres para eliminar en la captura de datos
        /// </summary>
        char[] x = { '\r', '\a', '\n' };


        /// <summary>
        /// Campo de tipo double que almacena el importe bruto
        /// </summary>
        double totalGrossAmount = 0;

        /// <summary>
        /// Campo de tipo double que almacena el importe de los impuestos repercutidos
        /// </summary>
        double totalTaxOutputs = 0;

        /// <summary>
        /// Campo de tipo double que almacena el importe bruto antes de impuestos
        /// </summary>
        double totalGrossAmountBeforeTaxes = 0;

        /// <summary>
        /// Campo de tipo double que almacena el importe total de los descuentos generales
        /// </summary>
        double totalGeneralDiscounts = 0;

        /// <summary>
        /// Campo de tipo double que almacena el importe de los impuestos retenidos
        /// </summary>
        double totalIRPF = 0;

        /// <summary>
        /// Campo que contiene los datos de la factura
        /// </summary>
        FacturaeFieldAndValues datos = null;

        /// <summary>
        /// Cultura de Office que determina los formatos numericos, fechas y monedas
        /// </summary>
        CultureInfo culturaOffice;

        /// <summary>
        /// Cultura de la factura que determina los formatos numericos, fechas y monedas
        /// </summary>
        CultureInfo culturaFactura;

        #endregion

        #region "Properties"
        /// <summary>
        /// Campo con la factura en formato CII
        /// </summary>
        public CrossIndustryInvoice Invoice { get; set; }

        #endregion

        #region "Constructors"


        /// <summary>
        /// Contructor por defecto
        /// </summary>
        public CIIGenerator()
        {
            culturaOffice = new CultureInfo(Globals.ThisAddIn.Application.LanguageSettings.get_LanguageID(Microsoft.Office.Core.MsoAppLanguageID.msoLanguageIDUI));
            culturaFactura = new CultureInfo("en-US");
            enumerateTables();
            Invoice = new CrossIndustryInvoice();
        }

        /// <summary>
        /// Contructor con parámetros
        /// </summary>
        /// <param name="datos">Datos de la factura</param>
        public CIIGenerator(FacturaeFieldAndValues datos)
        {
            culturaOffice = new CultureInfo(Globals.ThisAddIn.Application.LanguageSettings.get_LanguageID(Microsoft.Office.Core.MsoAppLanguageID.msoLanguageIDUI));
            culturaFactura = new CultureInfo("en-US");
            enumerateTables();
            this.datos = datos;
            Invoice = new CrossIndustryInvoice();
            header();
            seller();
            buyer();
            signatoryParty();
            lineasDetalle();
            descuentosGenerales();
            irpf();
            descuento();
            iva();
            resumenTotales();
        }

        #endregion

        #region "Creacion CII"

        /// <summary>
        /// Método que genera los datos de cabecera de la factura
        /// </summary>
        public void header()
        {
            //CultureInfo c = new CultureInfo("es-ES");
            Invoice.CIIHExchangedDocument.VersionID.Value = "1.0";//datos.getValueByFieldName("SchemaVersion");
            Invoice.CIIHExchangedDocument.ID.Value = datos.getValueByFieldName("IH_InvoiceSeriesCode") + "-" + datos.getValueByFieldName("IH_InvoiceNumber");
            if (datos.getValueByFieldName("IH_InvoiceClass").Equals("OO"))
            {
                Invoice.CIIHExchangedDocument.TypeCode = "80";
                Invoice.CIIHExchangedDocument.CopyIndicator.Value = false;
            }
            else if (datos.getValueByFieldName("IH_InvoiceClass").Equals("CO"))
            {
                Invoice.CIIHExchangedDocument.TypeCode = "80";
                Invoice.CIIHExchangedDocument.CopyIndicator.Value = true;
            }
            else if (datos.getValueByFieldName("IH_InvoiceClass").Equals("OR"))
            {
                Invoice.CIIHExchangedDocument.TypeCode = "82";
                Invoice.CIIHExchangedDocument.CopyIndicator.Value = false;
                if (Invoice.CIIHExchangedDocument.IncludedCINote == null)
                {
                    Invoice.CIIHExchangedDocument.IncludedCINote = new CINoteType();
                }
                Invoice.CIIHExchangedDocument.IncludedCINote.Content.Value = datos.getValueByFieldName("CORR_ReasonDescription") + "/" + datos.getValueByFieldName("CORR_CorrectionMethodDescription");
                Invoice.CIExchangedDocumentContext.ApplicationSpecifiedCIDocumentContextParameter = new CIDocumentContextParameterType();
                Invoice.CIExchangedDocumentContext.ApplicationSpecifiedCIDocumentContextParameter.SpecifiedCIDocumentVersion.ID.Value = datos.getValueByFieldName("CORR_InvoiceSeriesCode") + "-" + datos.getValueByFieldName("CORR_InvoiceNumber");
                Invoice.CIExchangedDocumentContext.ApplicationSpecifiedCIDocumentContextParameter.SpecifiedCIDocumentVersion.IssueDateTime.Value = DateTime.Parse(datos.getValueByFieldName("CORR_TaxPeriod_StartDate").Trim(x).Trim(), culturaOffice).ToString("yyyy-MM-ddTHH:mm:ss");
            }
            else if (datos.getValueByFieldName("IH_InvoiceClass").Equals("CR"))
            {
                Invoice.CIIHExchangedDocument.TypeCode = "82";
                Invoice.CIIHExchangedDocument.CopyIndicator.Value = true;
                Invoice.CIIHExchangedDocument.IncludedCINote.Content.Value = datos.getValueByFieldName("CORR_ReasonDescription") + "/" + datos.getValueByFieldName("CORR_CorrectionMethodDescription");
                if (Invoice.CIIHExchangedDocument.IncludedCINote == null)
                {
                    Invoice.CIIHExchangedDocument.IncludedCINote = new CINoteType();
                }
                Invoice.CIIHExchangedDocument.IncludedCINote.Content.Value = datos.getValueByFieldName("CORR_ReasonDescription");
                Invoice.CIExchangedDocumentContext.ApplicationSpecifiedCIDocumentContextParameter = new CIDocumentContextParameterType();
                Invoice.CIExchangedDocumentContext.ApplicationSpecifiedCIDocumentContextParameter.SpecifiedCIDocumentVersion.ID.Value = datos.getValueByFieldName("CORR_InvoiceSeriesCode") + "-" + datos.getValueByFieldName("CORR_InvoiceNumber");
                Invoice.CIExchangedDocumentContext.ApplicationSpecifiedCIDocumentContextParameter.SpecifiedCIDocumentVersion.IssueDateTime.Value = DateTime.Parse(datos.getValueByFieldName("CORR_TaxPeriod_StartDate").Trim(x).Trim(), culturaOffice).ToString("yyyy-MM-ddTHH:mm:ss");
            }
            Invoice.CIIHExchangedDocument.IssueDateTime.Value = DateTime.Parse(datos.getValueByFieldName("InvIssue_IssueDate").Trim(x).Trim(), culturaOffice).ToString("yyyy-MM-ddTHH:mm:ss");
            //Invoice.DocumentCurrencyCode = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
        }


        /// <summary>
        /// Método que genera los datos del emisor
        /// </summary>
        public void seller()
        {
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.SpecifiedCILegalOrganization.ID.Value = datos.getValueByFieldName("SP_TaxIdentificationNumber");

            if (datos.getValueByFieldName("SP_PersonTypeCode").Equals("J"))
            {
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.SpecifiedCILegalOrganization.LegalClassificationCode.Value = "J";
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.SpecifiedCILegalOrganization.Name.Value = datos.getValueByFieldName("SP_CorporateName");
            }
            else
            {
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.SpecifiedCILegalOrganization.LegalClassificationCode.Value = "F";
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.SpecifiedCILegalOrganization.Name.Value = datos.getValueByFieldName("SP_Name") + " " + datos.getValueByFieldName("SP_FirstSurname") + " " + datos.getValueByFieldName("SP_SecondSurname");
            }
            if (!String.IsNullOrEmpty(datos.getValueByFieldName("SP_Telephone")))
            {
                if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.DefinedCITradeContact == null)
                {
                    Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.DefinedCITradeContact = new CITradeContactType();
                }
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.DefinedCITradeContact.TelephoneCIUniversalCommunication = new CIUniversalCommunicationType();
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.DefinedCITradeContact.TelephoneCIUniversalCommunication.CompleteNumber = new TextType();
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.DefinedCITradeContact.TelephoneCIUniversalCommunication.CompleteNumber.Value = datos.getValueByFieldName("SP_Telephone");

            }
            if (!String.IsNullOrEmpty(datos.getValueByFieldName("SP_email")))
            {
                if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.DefinedCITradeContact == null)
                {
                    Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.DefinedCITradeContact = new CITradeContactType();
                }
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.DefinedCITradeContact.EmailURICIUniversalCommunication = new CIUniversalCommunicationType();
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.DefinedCITradeContact.EmailURICIUniversalCommunication.URIID = new IDType();
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.DefinedCITradeContact.EmailURICIUniversalCommunication.URIID.Value = datos.getValueByFieldName("SP_email");
            }

            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.PostalCITradeAddress.StreetName.Value = datos.getValueByFieldName("SP_Address");
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.PostalCITradeAddress.CityName.Value = datos.getValueByFieldName("SP_Town");
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.PostalCITradeAddress.PostcodeCode.Value = datos.getValueByFieldName("SP_PostCode");
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.PostalCITradeAddress.CitySubDivisionName.Value = datos.getValueByFieldName("SP_Province");
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.PostalCITradeAddress.CountryID.Value = datos.getValueByFieldName("SP_CountryCode");
        }


        /// <summary>
        /// Método que genera los datos del receptor
        /// </summary>
        public void buyer()
        {
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.SpecifiedCILegalOrganization.ID.Value = datos.getValueByFieldName("BP_TaxIdentificationNumber");

            if (datos.getValueByFieldName("BP_PersonTypeCode").Equals("J"))
            {
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.SpecifiedCILegalOrganization.LegalClassificationCode.Value = "J";
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.SpecifiedCILegalOrganization.Name.Value = datos.getValueByFieldName("BP_CorporateName");
            }
            else
            {
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.SpecifiedCILegalOrganization.LegalClassificationCode.Value = "F";
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.SpecifiedCILegalOrganization.Name.Value = datos.getValueByFieldName("BP_Name") + " " + datos.getValueByFieldName("BP_FirstSurname") + " " + datos.getValueByFieldName("BP_SecondSurname");
            }

            if (!String.IsNullOrEmpty(datos.getValueByFieldName("BP_Telephone")))
            {
                if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.DefinedCITradeContact == null)
                {
                    Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.DefinedCITradeContact = new CITradeContactType();
                }
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.DefinedCITradeContact.TelephoneCIUniversalCommunication = new CIUniversalCommunicationType();
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.DefinedCITradeContact.TelephoneCIUniversalCommunication.CompleteNumber = new TextType();
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.DefinedCITradeContact.TelephoneCIUniversalCommunication.CompleteNumber.Value = datos.getValueByFieldName("BP_Telephone");

            }
            if (!String.IsNullOrEmpty(datos.getValueByFieldName("BP_email")))
            {
                if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.DefinedCITradeContact == null)
                {
                    Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.DefinedCITradeContact = new CITradeContactType();
                }
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.DefinedCITradeContact.EmailURICIUniversalCommunication = new CIUniversalCommunicationType();
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.DefinedCITradeContact.EmailURICIUniversalCommunication.URIID = new IDType();
                Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.DefinedCITradeContact.EmailURICIUniversalCommunication.URIID.Value = datos.getValueByFieldName("BP_email");
            }

            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.PostalCITradeAddress.StreetName.Value = datos.getValueByFieldName("BP_Address");
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.PostalCITradeAddress.CityName.Value = datos.getValueByFieldName("BP_Town");
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.PostalCITradeAddress.PostcodeCode.Value = datos.getValueByFieldName("BP_PostCode");
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.PostalCITradeAddress.CitySubDivisionName.Value = datos.getValueByFieldName("BP_Province");
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.PostalCITradeAddress.CountryID.Value = datos.getValueByFieldName("BP_CountryCode");

        }

        /// <summary>
        /// Método que genera los datos del tercero
        /// </summary>
        public void signatoryParty()
        {
            //Invoice.Signature.SignatoryParty.PartyIdentification.ID = datos.getValueByFieldName("TH_TaxIdentificationNumber");


            //if (datos.getValueByFieldName("InvoiceIssuerType").Equals("TE"))
            //{
            //    if (datos.getValueByFieldName("TH_PersonTypeCode").Equals("J"))
            //    {
            //        Invoice.Signature.SignatoryParty.PartyName.Name = datos.getValueByFieldName("TH_CorporateName");
            //        Invoice.Signature.SignatoryParty.PartyLegalEntity = new PartyLegalEntity();
            //        Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationName = datos.getValueByFieldName("TH_CorporateName");
            //        Invoice.Signature.SignatoryParty.PartyLegalEntity.CompanyID = datos.getValueByFieldName("TH_TaxIdentificationNumber");
            //        Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.StreetName = datos.getValueByFieldName("TH_Address");
            //        Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.CityName = datos.getValueByFieldName("TH_Town");
            //        Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.PostalZone = datos.getValueByFieldName("TH_PostCode");
            //        Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.CountrySubentity = datos.getValueByFieldName("TH_Province");
            //        Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.Country.IdentificationCode = datos.getValueByFieldName("TH_CountryCode");

            //    }
            //    else
            //    {
            //        Invoice.Signature.SignatoryParty.PartyName.Name = datos.getValueByFieldName("TH_Name") + " " + datos.getValueByFieldName("TH_FirstSurname") + " " + datos.getValueByFieldName("TH_FirstSurname");
            //        Invoice.Signature.SignatoryParty.Person = new Person();
            //        Invoice.Signature.SignatoryParty.Person.FirstName = datos.getValueByFieldName("TH_Name");
            //        Invoice.Signature.SignatoryParty.Person.FamilyName = datos.getValueByFieldName("TH_FirstSurname") + " " + datos.getValueByFieldName("TH_FirstSurname");
            //        Invoice.Signature.SignatoryParty.PartyTaxScheme = new PartyTaxScheme();
            //        Invoice.Signature.SignatoryParty.PartyTaxScheme.RegistrationName = datos.getValueByFieldName("TH_Name");
            //        Invoice.Signature.SignatoryParty.PartyTaxScheme.CompanyID = datos.getValueByFieldName("TH_TaxIdentificationNumber");
            //        Invoice.Signature.SignatoryParty.PostalAddress = new PostalAddress();
            //        Invoice.Signature.SignatoryParty.PostalAddress.StreetName = datos.getValueByFieldName("TH_Address");
            //        Invoice.Signature.SignatoryParty.PostalAddress.CityName = datos.getValueByFieldName("TH_Town");
            //        Invoice.Signature.SignatoryParty.PostalAddress.PostalZone = datos.getValueByFieldName("TH_PostCode");
            //        Invoice.Signature.SignatoryParty.PostalAddress.CountrySubentity = datos.getValueByFieldName("TH_Province");
            //        Invoice.Signature.SignatoryParty.PostalAddress.Country.IdentificationCode = datos.getValueByFieldName("TH_CountryCode");

            //    }
            //}
            //else
            //{
            //    if (datos.getValueByFieldName("SP_PersonTypeCode").Equals("J"))
            //    {
            //        Invoice.Signature.SignatoryParty.PartyName.Name = datos.getValueByFieldName("SP_CorporateName");
            //        Invoice.Signature.SignatoryParty.PartyLegalEntity = new PartyLegalEntity();
            //        Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationName = datos.getValueByFieldName("SP_CorporateName");
            //        Invoice.Signature.SignatoryParty.PartyLegalEntity.CompanyID = datos.getValueByFieldName("SP_TaxIdentificationNumber");
            //        Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.StreetName = datos.getValueByFieldName("SP_Address");
            //        Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.BuildingNumber = datos.getValueByFieldName("SP_BuildingNumber");
            //        Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.CityName = datos.getValueByFieldName("SP_Town");
            //        Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.PostalZone = datos.getValueByFieldName("SP_PostCode");
            //        Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.CountrySubentity = datos.getValueByFieldName("SP_Province");
            //        Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.Country.IdentificationCode = datos.getValueByFieldName("SP_CountryCode");

            //    }
            //    else
            //    {
            //        Invoice.Signature.SignatoryParty.PartyName.Name = datos.getValueByFieldName("SP_Name") + " " + datos.getValueByFieldName("SP_FirstSurname") + " " + datos.getValueByFieldName("SP_FirstSurname");
            //        Invoice.Signature.SignatoryParty.Person = new Person();
            //        Invoice.Signature.SignatoryParty.Person.FirstName = datos.getValueByFieldName("SP_Name");
            //        Invoice.Signature.SignatoryParty.Person.FamilyName = datos.getValueByFieldName("SP_FirstSurname") + " " + datos.getValueByFieldName("SP_FirstSurname");
            //        Invoice.Signature.SignatoryParty.PartyTaxScheme = new PartyTaxScheme();
            //        Invoice.Signature.SignatoryParty.PartyTaxScheme.RegistrationName = datos.getValueByFieldName("SP_Name");
            //        Invoice.Signature.SignatoryParty.PartyTaxScheme.CompanyID = datos.getValueByFieldName("SP_TaxIdentificationNumber");
            //        Invoice.Signature.SignatoryParty.PostalAddress = new PostalAddress();
            //        Invoice.Signature.SignatoryParty.PostalAddress.StreetName = datos.getValueByFieldName("SP_Address");
            //        Invoice.Signature.SignatoryParty.PostalAddress.BuildingNumber = datos.getValueByFieldName("SP_BuildingNumber");
            //        Invoice.Signature.SignatoryParty.PostalAddress.CityName = datos.getValueByFieldName("SP_Town");
            //        Invoice.Signature.SignatoryParty.PostalAddress.PostalZone = datos.getValueByFieldName("SP_PostCode");
            //        Invoice.Signature.SignatoryParty.PostalAddress.CountrySubentity = datos.getValueByFieldName("SP_Province");
            //        Invoice.Signature.SignatoryParty.PostalAddress.Country.IdentificationCode = datos.getValueByFieldName("SP_CountryCode");

            //    }
            //}
        }


        /// <summary>
        /// Método que genera los descuentos generales
        /// </summary>
        public void descuentosGenerales()
        {
            CITradeAllowanceChargeType descuentoGeneral = null;
            datos.generalDiscount = getGeneralDiscounts();
            if (datos.generalDiscount != null)
            {
                for (int i = 0; i < datos.generalDiscount.Count; i++)
                {
                    if (!double.Parse(datos.generalDiscount[i].discountRate, culturaOffice.NumberFormat).Equals(double.Parse("0", culturaOffice.NumberFormat)))
                    {


                        descuentoGeneral = new CITradeAllowanceChargeType();
                        descuentoGeneral.ReasonCode.Value = "1";
                        descuentoGeneral.Reason.Value = datos.generalDiscount[i].Reason;
                        //descuentoGeneral.BaseAmount.Value = cambiarComasPorPuntos(String.Format("{0:0.00}", datos.generalDiscount[i].baseImponible));
                        descuentoGeneral.ActualAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.generalDiscount[i].totalDescuento);
                        descuentoGeneral.CalculationPercent.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.generalDiscount[i].discountRate);
                        //descuentoGeneral.BaseAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        descuentoGeneral.ActualAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge == null)
                        {
                            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge = new List<CITradeAllowanceChargeType>();
                        }
                        Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge.Add(descuentoGeneral);
                    }
                }
            }
        }


        /// <summary>
        /// Método que genera los impuestos retenidos
        /// </summary>
        public void irpf()
        {
            CITradeTaxType irpf = null;
            for (int i = 0; i < datos.lineDetails.Count; i++)
            {
                irpf = new CITradeTaxType();
                if (!String.IsNullOrEmpty(datos.lineDetails[i].IRPFTaxRate) && (!double.Parse(datos.lineDetails[i].IRPFTaxRate, culturaOffice.NumberFormat).Equals(double.Parse("0", culturaOffice.NumberFormat))))
                {
                    if (!addIfExist(datos.lineDetails[i].IRPFTaxRate, datos.lineDetails[i].IRPFAmount, datos.lineDetails[i].BaseImponible, 1))
                    {
                        irpf.CategoryCode.Value = "IRPF";
                        irpf.CalculatedRate.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].IRPFTaxRate);
                        irpf.BasisAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].BaseImponible);//String.Format(numberFormat, "{0:0.00}", datos.lineDetails[i].BaseImponible);
                        irpf.BasisAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        irpf.CalculatedAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].IRPFAmount);
                        irpf.CalculatedAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        irpf.CurrencyCode.Value = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax == null)
                        {
                            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax = new List<CITradeTaxType>();
                        }
                        Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax.Add(irpf);
                    }
                }
            }

        }

        /// <summary>
        /// Método que genera los descuentos a nivel de linea
        /// </summary>
        public void descuento()
        {
            CITradeAllowanceChargeType descuento = null;
            for (int i = 0; i < datos.lineDetails.Count; i++)
            {
                descuento = new CITradeAllowanceChargeType();
                if (!String.IsNullOrEmpty(datos.lineDetails[i].DiscountRate) && (!double.Parse(datos.lineDetails[i].DiscountRate, culturaOffice.NumberFormat).Equals(double.Parse("0", culturaOffice.NumberFormat))))
                {
                    if (!addIfExist(datos.lineDetails[i].DiscountRate, datos.lineDetails[i].DiscountAmount, datos.lineDetails[i].BaseImponible, 2))
                    {
                        descuento.ReasonCode.Value = "2";
                        descuento.Reason.Value = "Discount";
                        descuento.CalculationPercent.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].DiscountRate);
                        //descuento.BaseAmount.Value = cambiarComasPorPuntos(String.Format("{0:0.00}", totalGrossAmountBeforeTaxes));//String.Format(numberFormat, "{0:0.00}", datos.lineDetails[i].BaseImponible);
                        //descuento.BaseAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        descuento.ActualAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].DiscountAmount);
                        descuento.ActualAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge == null)
                        {
                            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge = new List<CITradeAllowanceChargeType>();
                        }
                        Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge.Add(descuento);
                    }
                }
            }
        }


        /// <summary>
        /// Método que genera los impuestos repercutidos
        /// </summary>
        public void iva()
        {
            CITradeTaxType taxTotal = null;
            for (int i = 0; i < datos.lineDetails.Count; i++)
            {

                if (!String.IsNullOrEmpty(datos.lineDetails[i].TaxRate) && (!double.Parse(datos.lineDetails[i].TaxRate, culturaOffice.NumberFormat).Equals(double.Parse("0", culturaOffice.NumberFormat))))
                {
                    if (!addIfExist(datos.lineDetails[i].TaxRate, datos.lineDetails[i].TaxAmount, datos.lineDetails[i].BaseImponible, 0))
                    {
                        taxTotal = new CITradeTaxType();
                        taxTotal.CalculatedAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].TaxAmount);
                        taxTotal.CalculatedAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        taxTotal.BasisAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].BaseImponible);//datos.lineDetails[i].BaseImponible;
                        taxTotal.BasisAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        taxTotal.CalculatedRate.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].TaxRate);
                        taxTotal.CategoryCode.Value = "VAT";
                        taxTotal.CurrencyCode.Value = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax == null)
                        {
                            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax = new List<CITradeTaxType>();
                        }
                        Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax.Add(taxTotal);
                    }
                }
            }
        }

        /// <summary>
        /// Método que genera el resumen de totales
        /// </summary>
        public void resumenTotales()
        {
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCIIHTradeSettlementMonetarySummation.RoundingAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", totalGrossAmountBeforeTaxes);
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCIIHTradeSettlementMonetarySummation.RoundingAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCIIHTradeSettlementMonetarySummation.TaxTotalAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", totalTaxOutputs);
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCIIHTradeSettlementMonetarySummation.TaxTotalAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCIIHTradeSettlementMonetarySummation.GrandTotalAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", totalGrossAmount);
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCIIHTradeSettlementMonetarySummation.GrandTotalAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCIIHTradeSettlementMonetarySummation.TotalDiscountAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", totalGeneralDiscounts);
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCIIHTradeSettlementMonetarySummation.TotalDiscountAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCIIHTradeSettlementMonetarySummation.TotalPrepaidAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", totalGrossAmount - totalGeneralDiscounts + totalTaxOutputs - totalIRPF);
            Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCIIHTradeSettlementMonetarySummation.TotalPrepaidAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
            //Invoice.LegalMonetaryTotal.PayableAmount = "InvoiceTotal";
        }


        /// <summary>
        /// Método que genera las linea de detalle de la factura
        /// </summary>
        public void lineasDetalle()
        {
            //CultureInfo c = new CultureInfo("es-ES");
            CIILSupplyChainTradeLineItemType line = null;
            CITradeAllowanceChargeType descuento = null;
            CITradeTaxType irpf = null;
            CITradeTaxType iva = null;
            datos.lineDetails = getItems();
            for (int i = 0; i < datos.lineDetails.Count; i++)
            {

                line = new CIILSupplyChainTradeLineItemType();
                line.AssociatedCIILDocumentLineDocument.LineID.Value = (i + 1).ToString();
                line.SpecifiedCIILSupplyChainTradeDelivery.SpecifiedCIDeliveryAdjustment.ActualQuantity.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].Quantity);
                line.SpecifiedCIILSupplyChainTradeDelivery.SpecifiedCIDeliveryAdjustment.ActualAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].UnitPriceWithoutTax);
                line.SpecifiedCIILSupplyChainTradeDelivery.SpecifiedCIDeliveryAdjustment.ActualAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");

                if (!String.IsNullOrEmpty(datos.lineDetails[i].TransactionDate))
                {
                    line.SpecifiedCIILSupplyChainTradeDelivery.SpecifiedCIDeliveryAdjustment.ActualDateTime.Value = DateTime.Parse(datos.lineDetails[i].TransactionDate.Trim(x).Trim(), culturaOffice).ToString("yyyy-MM-ddTHH:mm:ss");
                }
                if (!String.IsNullOrEmpty(datos.lineDetails[i].DiscountRate) && (!double.Parse(datos.lineDetails[i].DiscountRate, culturaOffice.NumberFormat).Equals(double.Parse("0", culturaOffice.NumberFormat))))
                {
                    descuento = new CITradeAllowanceChargeType();
                    if (line.SpecifiedCIILSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge == null)
                    {
                        line.SpecifiedCIILSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge = new List<CITradeAllowanceChargeType>();
                    }
                    descuento.ReasonCode.Value = "2";
                    descuento.Reason.Value = "Discount";
                    descuento.CalculationPercent.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].DiscountRate);
                    //descuento.BaseAmount.Value = cambiarComasPorPuntos(String.Format("{0:0.00}", datos.lineDetails[i].BaseImponible));
                    //descuento.BaseAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                    descuento.ActualAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].DiscountAmount);
                    descuento.ActualAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                    line.SpecifiedCIILSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge.Add(descuento);
                }
                if (!String.IsNullOrEmpty(datos.lineDetails[i].IRPFTaxRate) && (!double.Parse(datos.lineDetails[i].IRPFTaxRate, culturaOffice.NumberFormat).Equals(double.Parse("0", culturaOffice.NumberFormat))))
                {
                    irpf = new CITradeTaxType();
                    if (line.SpecifiedCIILSupplyChainTradeSettlement.ApplicableCITradeTax == null)
                    {
                        line.SpecifiedCIILSupplyChainTradeSettlement.ApplicableCITradeTax = new List<CITradeTaxType>();
                    }
                    irpf.CategoryCode.Value = "IRPF";
                    irpf.CalculatedRate.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].IRPFTaxRate);
                    irpf.CalculatedAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                    irpf.BasisAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].BaseImponible);
                    irpf.BasisAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                    irpf.CalculatedAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].IRPFAmount);
                    irpf.CalculatedAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                    irpf.CurrencyCode.Value = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode"); ;
                    line.SpecifiedCIILSupplyChainTradeSettlement.ApplicableCITradeTax.Add(irpf);
                }
                if (!String.IsNullOrEmpty(datos.lineDetails[i].TaxRate) && (!double.Parse(datos.lineDetails[i].TaxRate, culturaOffice.NumberFormat).Equals(double.Parse("0", culturaOffice.NumberFormat))))
                {
                    iva = new CITradeTaxType();
                    if (line.SpecifiedCIILSupplyChainTradeSettlement.ApplicableCITradeTax == null)
                    {
                        line.SpecifiedCIILSupplyChainTradeSettlement.ApplicableCITradeTax = new List<CITradeTaxType>();
                    }
                    iva.CalculatedAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].TaxAmount);
                    iva.CalculatedAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                    iva.BasisAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].BaseImponible);
                    iva.BasisAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                    iva.CalculatedRate.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].TaxRate);
                    iva.CategoryCode.Value = "VAT";
                    iva.CurrencyCode.Value = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                    //iva.UnitBasisAmount = new AmountType();
                    //iva.UnitBasisAmount.Value = cambiarComasPorPuntos(String.Format("{0:0.00}", datos.lineDetails[i].UnitPriceWithoutTax));
                    //iva.UnitBasisAmount.currencyCode = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                    line.SpecifiedCIILSupplyChainTradeSettlement.ApplicableCITradeTax.Add(iva);
                }
                line.SpecifiedCIILSupplyChainTradeSettlement.SpecifiedCIILTradeSettlementMonetarySummation.LineTotalAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].TotalImport);
                line.SpecifiedCIILSupplyChainTradeSettlement.SpecifiedCIILTradeSettlementMonetarySummation.LineTotalAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                line.SpecifiedCITradeProduct.Name.Value = datos.lineDetails[i].Descripcion;

                Invoice.CIIHSupplyChainTradeTransaction.IncludedCIILSupplyChainTradeLineItem.Add(line);

            }



            
        }

        /// <summary>
        /// Método que calcula el valor de los descuentos generales
        /// </summary>
        /// <returns>Lista con los descuentos generales</returns>
        private List<GeneralDiscountType> getGeneralDiscounts()
        {
            List<GeneralDiscountType> generalDiscounts = null;
            if (document.Tables[t3].Rows.Count > 3)
            {
                generalDiscounts = new List<GeneralDiscountType>();
                GeneralDiscountType discount = null;
                double discountAmount = 0;

                for (int i = 3; i < document.Tables[t3].Rows.Count; i++)
                {
                    discount = new GeneralDiscountType();
                    double discountRate = Round3(double.Parse(document.Tables[t3].Rows[i].Cells[2].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2);

                    if (discountRate != 0)
                    {
                        discountAmount = Round3(((double.Parse(datos.Totals.TotalGrossAmount, culturaOffice.NumberFormat) * discountRate) / 100), 2);
                    }

                    totalGeneralDiscounts += Round3(discountAmount, 2);
                    discount.Reason = document.Tables[t3].Rows[i].Cells[1].Range.Text.Trim(x).Trim();
                    discount.discountRate = String.Format(culturaFactura.NumberFormat, "{0:0.00}", discountRate);
                    discount.totalDescuento = String.Format(culturaFactura.NumberFormat, "{0:0.00}", discountAmount);
                    discount.baseImponible = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.Totals.TotalGrossAmount);
                    generalDiscounts.Add(discount);
                }
                totalGrossAmountBeforeTaxes = totalGrossAmount - totalGeneralDiscounts;
            }

            return generalDiscounts;
        }


        /// <summary>
        /// Método que comprueba si un tipo de impuesto existe, con lo cual incrementa el importe
        /// o por el contrario no existe, lo creo nuevo
        /// </summary>
        /// <param name="percent">Porcentaje del impuesto</param>
        /// <param name="amount">Importe</param>
        /// <param name="baseImponible">BaseImponible</param>
        /// <param name="type">Tipo de impuesto</param>
        /// <returns>True o False si existe el tipo de impuesto</returns>
        private bool addIfExist(String iva, String amount, String baseImponible, int type)
        {
            switch (type)
            {
                //Tipo IVA
                case 0:
                    {
                        if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax != null)
                        {
                            for (int i = 0; i < Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax.Count; i++)
                            {
                                if (iva.Equals(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].CalculatedRate.Value) && Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].CategoryCode.Value.Equals("VAT"))
                                {
                                    Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].CalculatedAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3((double.Parse(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].CalculatedAmount.Value, culturaFactura.NumberFormat) + double.Parse(amount, culturaFactura.NumberFormat)), 2));
                                    Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].CalculatedAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                                    Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].BasisAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3((double.Parse(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].BasisAmount.Value, culturaFactura.NumberFormat) + double.Parse(baseImponible, culturaFactura.NumberFormat)), 2));
                                    return true;
                                }
                            }
                        }

                    } break;
                //Tipo IRPF
                case 1:
                    {
                        if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax != null)
                        {
                            for (int i = 0; i < Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax.Count; i++)
                            {
                                if (iva.Equals(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].CalculatedRate.Value) && Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].CategoryCode.Value.Equals("IRPF"))
                                {
                                    Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].CalculatedAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3((double.Parse(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].CalculatedAmount.Value, culturaFactura.NumberFormat) + double.Parse(amount, culturaFactura.NumberFormat)), 2));
                                    Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].CalculatedAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                                    Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].BasisAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3((double.Parse(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].BasisAmount.Value, culturaFactura.NumberFormat) + double.Parse(baseImponible, culturaFactura.NumberFormat)), 2));
                                    return true;
                                }
                            }
                        }

                    } break;
                //Tipo Descuento
                case 2:
                    {
                        if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge != null)
                        {
                            for (int i = 0; i < Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge.Count; i++)
                            {
                                if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge[i].ReasonCode.Value.Equals("2") && iva.Equals(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge[i].CalculationPercent.Value))
                                {
                                    Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge[i].ActualAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3((double.Parse(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge[i].ActualAmount.Value, culturaFactura.NumberFormat) + double.Parse(amount, culturaFactura.NumberFormat)), 2));
                                    Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge[i].ActualAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                                    return true;
                                }
                            }
                        }

                    } break;
            }

            return false;
        }



        /// <summary>
        /// Se encarga de realzar los cálculos y operaciones necesarias para registrar cada uno de los detalles 
        /// en el listado de ítems de la factura
        /// </summary>
        /// <returns>El Listado cargado con las líneas de detalle</returns>
        private List<TypeLineDetails> getItems()
        {
            List<TypeLineDetails> items = new List<TypeLineDetails>();


            if (document.Tables[t2].Rows.Count > 3)
            {

                /*recorremos todas las filas de la tabla para agregar los registros a la lista de itemes*/

                for (int i = 3; i < document.Tables[t2].Rows.Count; i++)
                {

                    TypeLineDetails item = new TypeLineDetails();

                    double Quantity = double.Parse(document.Tables[t2].Rows[i].Cells[3].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat);

                    double unitPriceWithoutTax = Round3(double.Parse(document.Tables[t2].Rows[i].Cells[4].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2);

                    double discountRate = Round3(double.Parse(document.Tables[t2].Rows[i].Cells[5].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2);

                    double taxRate = Round3(double.Parse(document.Tables[t2].Rows[i].Cells[6].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2);

                    double IRPFTaxRate = Round3(double.Parse(document.Tables[t2].Rows[i].Cells[7].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2);

                    double discountAmount = Round3(((Quantity * unitPriceWithoutTax) * discountRate) / 100, 2);

                    double baseImponible = Round3((Quantity * unitPriceWithoutTax) - discountAmount, 2);

                    double IVAAmount = Round3(baseImponible * taxRate / 100, 2);

                    double IRPFAmount = Round3(baseImponible * (IRPFTaxRate / 100), 2);

                    //double total = Round3((baseImponible + (IVAAmount - IRPFAmount)), 2);

                    //CultureInfo cult = new CultureInfo("es-ES");

                    DateTime transactionDate = DateTime.Parse(document.Tables[t2].Rows[i].Cells[1].Range.Text.Trim(x).Trim(), culturaOffice);

                    item.TransactionDate = transactionDate.ToString("yyyy-MM-dd");
                    item.Descripcion = document.Tables[t2].Rows[i].Cells[2].Range.Text.Trim(x).Trim();
                    item.Quantity = int.Parse(Quantity.ToString()).ToString();
                    item.UnitPriceWithoutTax = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3(double.Parse(document.Tables[t2].Rows[i].Cells[4].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2));
                    item.DiscountRate = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3(double.Parse(document.Tables[t2].Rows[i].Cells[5].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2));
                    item.TaxRate = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3(double.Parse(document.Tables[t2].Rows[i].Cells[6].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2));
                    item.IRPFTaxRate = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3(double.Parse(document.Tables[t2].Rows[i].Cells[7].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2));
                    item.BaseImponible = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3(double.Parse(document.Tables[t2].Rows[i].Cells[8].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2));
                    item.TotalImport = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3(double.Parse(document.Tables[t2].Rows[i].Cells[9].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2));

                    item.DiscountAmount = String.Format(culturaFactura.NumberFormat, "{0:0.00}", discountAmount);
                    item.IRPFAmount = String.Format(culturaFactura.NumberFormat, "{0:0.00}", IRPFAmount);
                    item.TaxAmount = String.Format(culturaFactura.NumberFormat, "{0:0.00}", IVAAmount);

                    //totalGrossAmount += Round3(total, 2);
                    totalGrossAmount += Round3(baseImponible, 2);
                    totalTaxOutputs += Round3(IVAAmount, 2);
                    totalIRPF += Round3(IRPFAmount, 2);
                    totalGrossAmountBeforeTaxes += Round3(baseImponible, 2);
                    //totalGeneralDiscounts = Round3(discountAmount,2);
                    items.Add(item);
                }
                datos.Totals.TotalGrossAmount += String.Format(culturaFactura.NumberFormat, "{0:0.00}", totalGrossAmount);
                datos.Totals.TotalTaxOutputs += String.Format(culturaFactura.NumberFormat, "{0:0.00}", totalTaxOutputs);
                //datos.Totals.TotalGrossAmountBeforeTaxes += String.Format("{0:0.00}", totalGrossAmountBeforeTaxes);
                //datos.Totals.TotalGeneralDiscounts = String.Format("{0:0.00}", totalGeneralDiscounts);
            }
            else
            {
                ControlMessages controlM = ControlMessages.getInstance();

                throw new Exception(controlM.getMessage(ControlMessages.Msg.ErrorInvoiceHaveNotDetails));
            }

            return items;
        }


        #endregion

        #region "Importacion CII"

        /// <summary>
        /// Método encargado de generar un objeto CII con los datos cargados de una factura
        /// </summary>
        public void loadData()
        {
            setHeader();
            setSeller();
            setBuyer();
            //if (!Invoice.AccountingSupplierParty.Party.PartyIdentification.ID.ToLower().Equals(Invoice.Signature.SignatoryParty.PartyIdentification.ID.ToLower()))
            //{
            //    setSignatoryParty();
            //}
            setlineasDetalles();
            setDecuentosGenerales();
            setTotales();
        }

        /// <summary>
        /// Método que importa los datos de cabecera
        /// </summary>
        public void setHeader()
        {
            setControlValue("SchemaVersion", Invoice.CIIHExchangedDocument.VersionID.Value);
            setControlValue("IH_InvoiceSeriesCode", Invoice.CIIHExchangedDocument.ID.Value.Substring(0, Invoice.CIIHExchangedDocument.ID.Value.IndexOf("-")));
            setControlValue("IH_InvoiceNumber", Invoice.CIIHExchangedDocument.ID.Value.Substring(Invoice.CIIHExchangedDocument.ID.Value.IndexOf("-") + 1));
            setControlValue("InvIssue_IssueDate", Convert.ToDateTime(Invoice.CIIHExchangedDocument.IssueDateTime.Value, culturaOffice).ToString(culturaOffice.DateTimeFormat.ShortDatePattern));
            //setControlValue("InvIssue_InvoiceCurrencyCode", Invoice.DocumentCurrencyCode);
            setControlValue("InvIssue_InvoiceCurrencyCode", "EUR");
            setControlValue("ExchangeRate", getExchangeRate());
            if (Invoice.CIIHExchangedDocument.CopyIndicator.Value.ToString().ToLower().Equals("false"))
            {
                setControlValue("IH_InvoiceClass", "OO");
            }
            else if (Invoice.CIIHExchangedDocument.CopyIndicator.Value.ToString().ToLower().Equals("true"))
            {
                setControlValue("IH_InvoiceClass", "CO");
            }
            if (Invoice.CIIHExchangedDocument.TypeCode.ToLower().Equals("82".ToLower()))
            {
                String[] corrective = Invoice.CIIHExchangedDocument.IncludedCINote.Content.Value.Split(new Char[] { '/' });
                if (corrective.Length > 0)
                {
                    setControlValue("CORR_ReasonDescription", corrective[0]);
                }
                if (corrective.Length > 1)
                {
                    setControlValue("CORR_CorrectionMethodDescription", corrective[1]);
                }
                setControlValue("CORR_InvoiceSeriesCode", Invoice.CIExchangedDocumentContext.ApplicationSpecifiedCIDocumentContextParameter.SpecifiedCIDocumentVersion.ID.Value.Substring(0, Invoice.CIExchangedDocumentContext.ApplicationSpecifiedCIDocumentContextParameter.SpecifiedCIDocumentVersion.ID.Value.IndexOf("-")));
                setControlValue("CORR_InvoiceNumber", Invoice.CIExchangedDocumentContext.ApplicationSpecifiedCIDocumentContextParameter.SpecifiedCIDocumentVersion.ID.Value.Substring(Invoice.CIExchangedDocumentContext.ApplicationSpecifiedCIDocumentContextParameter.SpecifiedCIDocumentVersion.ID.Value.IndexOf("-") + 1));
                if (Invoice.CIIHExchangedDocument.CopyIndicator.Value.ToString().ToLower().Equals("false"))
                {
                    setControlValue("IH_InvoiceClass", "OR");
                }
                else if (Invoice.CIIHExchangedDocument.CopyIndicator.Value.ToString().ToLower().Equals("true"))
                {
                    setControlValue("IH_InvoiceClass", "CR");
                }
                setControlValue("CORR_TaxPeriod_StartDate", Convert.ToDateTime(Invoice.CIExchangedDocumentContext.ApplicationSpecifiedCIDocumentContextParameter.SpecifiedCIDocumentVersion.IssueDateTime.Value, culturaOffice).ToString(culturaOffice.DateTimeFormat.ShortDatePattern));
            }
        }

        /// <summary>
        /// Método que importa los datos del emisor
        /// </summary>
        public void setSeller()
        {
            if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty != null)
            {
                if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.SpecifiedCILegalOrganization.LegalClassificationCode.Value.ToUpper().Equals("J"))
                {
                    setControlValue("SP_PersonTypeCode", "J");
                    setControlValue("SP_CorporateName", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.SpecifiedCILegalOrganization.Name.Value);

                }
                else
                {
                    setControlValue("SP_PersonTypeCode", "F");

                    String[] nombre = Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.SpecifiedCILegalOrganization.Name.Value.Split(new char[] { ' ' });
                    setControlValue("SP_Name", nombre[0]);
                    if (nombre.Length > 1)
                    {
                        String aux = "";
                        for (int i = 1; i < nombre.Length; i++)
                        {
                            aux += nombre[i] + " ";
                        }
                        setControlValue("SP_FirstSurname", aux.Trim());
                    }

                    //setControlValue("SP_FirstSurname", Invoice.AccountingSupplierParty.Party.Person.FamilyName);
                }

                if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.DefinedCITradeContact != null)
                {
                    if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.DefinedCITradeContact.TelephoneCIUniversalCommunication != null)
                    {
                        if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.DefinedCITradeContact.TelephoneCIUniversalCommunication.CompleteNumber != null)
                        {
                            setControlValue("SP_Telephone", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.DefinedCITradeContact.TelephoneCIUniversalCommunication.CompleteNumber.Value);
                        }
                    }
                    if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.DefinedCITradeContact.EmailURICIUniversalCommunication != null)
                    {
                        if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.DefinedCITradeContact.EmailURICIUniversalCommunication.URIID != null)
                        {
                            setControlValue("SP_email", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.DefinedCITradeContact.EmailURICIUniversalCommunication.URIID.Value);
                        }
                    }

                }

                setControlValue("SP_TaxIdentificationNumber", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.SpecifiedCILegalOrganization.ID.Value);
                setControlValue("SP_Address", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.PostalCITradeAddress.StreetName.Value);
                setControlValue("SP_Town", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.PostalCITradeAddress.CityName.Value);
                setControlValue("SP_PostCode", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.PostalCITradeAddress.PostcodeCode.Value);
                setControlValue("SP_Province", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.PostalCITradeAddress.CitySubDivisionName.Value);
                setControlValue("SP_CountryCode", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.SellerCITradeParty.PostalCITradeAddress.CountryID.Value);
            }
        }

        /// <summary>
        /// Método que importa los datos del receptor
        /// </summary>
        public void setBuyer()
        {
            if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty != null)
            {
                if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.SpecifiedCILegalOrganization.LegalClassificationCode.Value.ToUpper().Equals("J"))
                {
                    setControlValue("BP_PersonTypeCode", "J");
                    setControlValue("BP_CorporateName", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.SpecifiedCILegalOrganization.Name.Value);

                }
                else
                {
                    setControlValue("BP_PersonTypeCode", "F");
                    setControlValue("BP_Name", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.SpecifiedCILegalOrganization.Name.Value);
                    String[] nombre = Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.SpecifiedCILegalOrganization.Name.Value.Split(new char[] { ' ' });
                    setControlValue("BP_Name", nombre[0]);
                    if (nombre.Length > 1)
                    {
                        String aux = "";
                        for (int i = 1; i < nombre.Length; i++)
                        {
                            aux += nombre[i] + " ";
                        }
                        setControlValue("BP_FirstSurname", aux.Trim());
                    }
                }
                if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.DefinedCITradeContact != null)
                {
                    if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.DefinedCITradeContact.TelephoneCIUniversalCommunication != null)
                    {
                        if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.DefinedCITradeContact.TelephoneCIUniversalCommunication.CompleteNumber != null)
                        {
                            setControlValue("BP_Telephone", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.DefinedCITradeContact.TelephoneCIUniversalCommunication.CompleteNumber.Value);
                        }
                    }
                    if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.DefinedCITradeContact.EmailURICIUniversalCommunication != null)
                    {
                        if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.DefinedCITradeContact.EmailURICIUniversalCommunication.URIID != null)
                        {
                            setControlValue("BP_email", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.DefinedCITradeContact.EmailURICIUniversalCommunication.URIID.Value);
                        }
                    }

                }
                setControlValue("BP_TaxIdentificationNumber", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.SpecifiedCILegalOrganization.ID.Value);
                setControlValue("BP_Address", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.PostalCITradeAddress.StreetName.Value);
                setControlValue("BP_Town", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.PostalCITradeAddress.CityName.Value);
                setControlValue("BP_PostCode", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.PostalCITradeAddress.PostcodeCode.Value);
                setControlValue("BP_Province", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.PostalCITradeAddress.CitySubDivisionName.Value);
                setControlValue("BP_CountryCode", Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeAgreement.BuyerCITradeParty.PostalCITradeAddress.CountryID.Value);
            }
        }


        /// <summary>
        /// Método que importa los datos del tercero
        /// </summary>
        public void setSignatoryParty()
        {
            //if (Invoice.Signature.SignatoryParty.PartyLegalEntity != null)
            //{
            //    setControlValue("TH_PersonTypeCode", "J");
            //    setControlValue("TH_CorporateName", Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationName);
            //    setControlValue("TH_TaxIdentificationNumber", Invoice.Signature.SignatoryParty.PartyLegalEntity.CompanyID);
            //    setControlValue("TH_Address", Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.StreetName);
            //    setControlValue("TH_BuildingNumber", Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.BuildingNumber);
            //    setControlValue("TH_Town", Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.CityName);
            //    setControlValue("TH_PostCode", Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.PostalZone);
            //    setControlValue("TH_Province", Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.CountrySubentity);
            //    setControlValue("TH_CountryCode", Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.Country.IdentificationCode);

            //}
            //else
            //{
            //    setControlValue("TH_PersonTypeCode", "F");
            //    setControlValue("TH_Name", Invoice.Signature.SignatoryParty.Person.FirstName);
            //    setControlValue("TH_FirstSurname", Invoice.Signature.SignatoryParty.Person.FamilyName);
            //    if (Invoice.Signature.SignatoryParty.PartyTaxScheme != null)
            //    {
            //        setControlValue("TH_Name", Invoice.Signature.SignatoryParty.PartyTaxScheme.RegistrationName);
            //        setControlValue("TH_TaxIdentificationNumber", Invoice.Signature.SignatoryParty.PartyTaxScheme.CompanyID);
            //    }
            //    if (Invoice.Signature.SignatoryParty.PostalAddress != null)
            //    {
            //        setControlValue("TH_Address", Invoice.Signature.SignatoryParty.PostalAddress.StreetName);
            //        setControlValue("TH_BuildingNumber", Invoice.Signature.SignatoryParty.PostalAddress.BuildingNumber);
            //        setControlValue("TH_Town", Invoice.Signature.SignatoryParty.PostalAddress.CityName);
            //        setControlValue("TH_PostCode", Invoice.Signature.SignatoryParty.PostalAddress.PostalZone);
            //        setControlValue("TH_Province", Invoice.Signature.SignatoryParty.PostalAddress.CountrySubentity);
            //        setControlValue("TH_CountryCode", Invoice.Signature.SignatoryParty.PostalAddress.Country.IdentificationCode);
            //    }
            //}
        }


        /// <summary>
        /// Método que importa los datos de las lineas de detalle
        /// </summary>
        public void setlineasDetalles()
        {
            document = Globals.ThisAddIn.Application.ActiveDocument;
            try
            {
                if (Invoice.CIIHSupplyChainTradeTransaction.IncludedCIILSupplyChainTradeLineItem.Count > 0)
                {
                    foreach (CIILSupplyChainTradeLineItemType item in Invoice.CIIHSupplyChainTradeTransaction.IncludedCIILSupplyChainTradeLineItem)
                    {
                        object rowBefore = document.Tables[t2].Rows.Last;
                        document.Tables[t2].Rows.Add(ref rowBefore);

                        document.Tables[t2].Rows.Last.Previous.Cells[1].Range.Text = Convert.ToDateTime(item.SpecifiedCIILSupplyChainTradeDelivery.SpecifiedCIDeliveryAdjustment.ActualDateTime.Value, culturaOffice).ToString(culturaOffice.DateTimeFormat.ShortDatePattern);
                        document.Tables[t2].Rows.Last.Previous.Cells[2].Range.Text = item.SpecifiedCITradeProduct.Name.Value;

                        document.Tables[t2].Rows.Last.Previous.Cells[3].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(item.SpecifiedCIILSupplyChainTradeDelivery.SpecifiedCIDeliveryAdjustment.ActualQuantity.Value, culturaFactura.NumberFormat));
                        document.Tables[t2].Rows.Last.Previous.Cells[4].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(item.SpecifiedCIILSupplyChainTradeDelivery.SpecifiedCIDeliveryAdjustment.ActualAmount.Value, culturaFactura.NumberFormat));
                        double discountRate = 0;
                        if (item.SpecifiedCIILSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge.Count == 0)
                        {
                            document.Tables[t2].Rows.Last.Previous.Cells[5].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse("0"));
                            document.Tables[t2].Rows.Last.Previous.Cells[7].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse("0"));
                        }
                        else
                        {
                            if (item.SpecifiedCIILSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge[0].ReasonCode.Value.Equals("2"))
                            {
                                if (double.TryParse(String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(item.SpecifiedCIILSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge[0].CalculationPercent.Value, culturaFactura.NumberFormat)), NumberStyles.Number, culturaOffice, out discountRate))
                                {
                                    document.Tables[t2].Rows.Last.Previous.Cells[5].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(item.SpecifiedCIILSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge[0].CalculationPercent.Value, culturaFactura.NumberFormat));
                                }
                                else
                                {
                                    document.Tables[t2].Rows.Last.Previous.Cells[5].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse("0"));
                                }

                            }
                        }
                        
                        double taxRate = 0;
                        double IRPFRate = 0;
                        if (item.SpecifiedCIILSupplyChainTradeSettlement.ApplicableCITradeTax.Count == 0)
                        {
                            document.Tables[t2].Rows.Last.Previous.Cells[6].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse("0"));
                            document.Tables[t2].Rows.Last.Previous.Cells[7].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse("0"));
                        }
                        for (int i = 0; i < item.SpecifiedCIILSupplyChainTradeSettlement.ApplicableCITradeTax.Count; i++)
                        {
                            if (item.SpecifiedCIILSupplyChainTradeSettlement.ApplicableCITradeTax[i].CategoryCode.Value.Equals("VAT"))
                            {
                                if (double.TryParse(String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(item.SpecifiedCIILSupplyChainTradeSettlement.ApplicableCITradeTax[i].CalculatedRate.Value, culturaFactura.NumberFormat)), NumberStyles.Number, culturaOffice, out taxRate))
                                {
                                    document.Tables[t2].Rows.Last.Previous.Cells[6].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(item.SpecifiedCIILSupplyChainTradeSettlement.ApplicableCITradeTax[i].CalculatedRate.Value, culturaFactura.NumberFormat));
                                }
                            }
                            else if (item.SpecifiedCIILSupplyChainTradeSettlement.ApplicableCITradeTax[i].CategoryCode.Value.Equals("IRPF"))
                            {

                                if (double.TryParse(String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(item.SpecifiedCIILSupplyChainTradeSettlement.ApplicableCITradeTax[i].CalculatedRate.Value, culturaFactura.NumberFormat)), NumberStyles.Number, culturaOffice, out IRPFRate))
                                {
                                    document.Tables[t2].Rows.Last.Previous.Cells[7].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(item.SpecifiedCIILSupplyChainTradeSettlement.ApplicableCITradeTax[i].CalculatedRate.Value, culturaFactura.NumberFormat));
                                }
                                else
                                {
                                    document.Tables[t2].Rows.Last.Previous.Cells[7].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse("0"));
                                }

                            }
                        }

                        double Quantity = Round3(double.Parse(item.SpecifiedCIILSupplyChainTradeDelivery.SpecifiedCIDeliveryAdjustment.ActualQuantity.Value, culturaFactura.NumberFormat), 2);

                        double unitPriceWithoutTax = double.Parse(item.SpecifiedCIILSupplyChainTradeDelivery.SpecifiedCIDeliveryAdjustment.ActualAmount.Value, culturaFactura.NumberFormat);

                        double descuento = ((Quantity * unitPriceWithoutTax) * discountRate) / 100;
                        double irpf = (((Quantity * unitPriceWithoutTax) - descuento) * IRPFRate) / 100;
                        double iva = (((Quantity * unitPriceWithoutTax) - descuento) * taxRate) / 100;

                        document.Tables[t2].Rows.Last.Previous.Cells[8].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", Round3(((Quantity * unitPriceWithoutTax) - descuento), 2));
                        document.Tables[t2].Rows.Last.Previous.Cells[9].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", Round3((((Quantity * unitPriceWithoutTax) - descuento) + (iva - irpf)), 2));
                    }
                }
            }
            catch (Exception) { }
        }

        /// <summary>
        /// Método que importa los datos de los descuentos generales
        /// </summary>
        public void setDecuentosGenerales()
        {
            if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge != null)
            {
                for (int i = 0; i < Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge.Count; i++)
                {
                    if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge[i].ReasonCode.Value.Equals("1"))
                    {
                        object rowBefore = document.Tables[t3].Rows.Last;
                        document.Tables[t3].Rows.Add(ref rowBefore);

                        document.Tables[t3].Rows.Last.Previous.Cells[1].Range.Text = Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge[i].Reason.Value;
                        document.Tables[t3].Rows.Last.Previous.Cells[2].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge[i].CalculationPercent.Value, culturaFactura.NumberFormat));
                        document.Tables[t3].Rows.Last.Previous.Cells[3].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCITradeAllowanceCharge[i].ActualAmount.Value, culturaFactura.NumberFormat));
                    }
                }
            }

        }

        /// <summary>
        /// Método que importa los datos de los totales
        /// </summary>
        public void setTotales()
        {
            Language language = Language.getInstance();

            try
            {
                document.Tables[t5].Rows[2].Cells[3].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCIIHTradeSettlementMonetarySummation.RoundingAmount.Value, culturaFactura.NumberFormat));

                try
                {
                    document.Tables[t5].Rows[3].Cells[3].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCIIHTradeSettlementMonetarySummation.TotalDiscountAmount.Value, culturaFactura.NumberFormat));

                }
                catch (Exception)
                {
                }
                double irpfAmount = (double)0;
                for (int i = 0; i < Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax.Count; i++)
                {
                    if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].CategoryCode.Value.Equals("VAT"))
                    {
                        object rowBefore = document.Tables[t5].Rows.Last;
                        document.Tables[t5].Rows.Last.Previous.Cells[2].Range.Text = language.getLabels("lbBaseAmount") + " (" + language.getLabels("lbVAT") + " " + int.Parse(double.Parse(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].CalculatedRate.Value, culturaFactura.NumberFormat).ToString()) + ")";
                        document.Tables[t5].Rows.Last.Previous.Cells[3].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].BasisAmount.Value, culturaFactura.NumberFormat));
                        document.Tables[t5].Rows.Add(ref rowBefore);
                        rowBefore = document.Tables[t5].Rows.Last;
                        document.Tables[t5].Rows.Last.Previous.Cells[2].Range.Text = language.getLabels("lbAmount") + " (" + language.getLabels("lbVAT") + " " + int.Parse(double.Parse(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].CalculatedRate.Value, culturaFactura.NumberFormat).ToString()) + ")";
                        document.Tables[t5].Rows.Last.Previous.Cells[3].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].CalculatedAmount.Value, culturaFactura.NumberFormat));
                        document.Tables[t5].Rows.Add(ref rowBefore);

                    }
                    else if (Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].CategoryCode.Value.Equals("IRPF"))
                    {
                        irpfAmount += double.Parse(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.ApplicableCITradeTax[i].CalculatedAmount.Value, culturaFactura.NumberFormat);
                    }
                }
                document.Tables[t5].Rows.Last.Previous.Cells[2].Range.Text = language.getLabels("lbIRPF");
                document.Tables[t5].Rows.Last.Previous.Cells[3].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", irpfAmount);
                document.Tables[t5].Rows.Last.Cells[3].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(Invoice.CIIHSupplyChainTradeTransaction.ApplicableCIIHSupplyChainTradeSettlement.SpecifiedCIIHTradeSettlementMonetarySummation.TotalPrepaidAmount.Value, culturaFactura.NumberFormat));

            }
            catch (Exception) { }
        }

        #endregion

        #region "Metodos Internos"


        /// <summary>
        /// Método que se encarga de numerar las tablas
        /// </summary>
        private void enumerateTables()
        {
            try
            {

                document = Globals.ThisAddIn.Application.ActiveDocument;

                int count = document.Tables.Count;
                if (count <= 0)
                {
                    ControlMessages msg = ControlMessages.getInstance();
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorNotValidTemplate));
                }

                else
                {

                    for (int i = 2; i <= document.Tables.Count; i++)
                    {
                        try
                        {
                            string table = document.Tables[i].Rows[1].Cells[1].Range.Text.Trim(x).Trim();
                            switch (table)
                            {

                                case "2":
                                    t2 = i; break;
                                case "3":
                                    t3 = i; break;
                                case "6":
                                    t4 = i; break;
                                case "4":
                                    t5 = i; break;
                                case "1":
                                    t6 = i; break;
                                case "7":
                                    t7 = i; break;

                            }
                        }
                        catch (Exception) { }
                    }
                }
            }
            catch (Exception) { }

        }


        /// <summary>
        /// Método encargado de realizar el redondeo
        /// </summary>
        /// <param name="numero">Numero que se desea redondear</param>
        /// <param name="decimales">Numero de decimales</param>
        /// <returns>Un String con el valor redondeado</returns>
        public static double Round3(double numero, int decimales)
        {
            double multi = Math.Pow(10.0d, (double)decimales);

            if (numero < 0)
                return (-(long)((-numero * multi) + 0.5d)) / multi;
            else
                return ((long)((numero * multi) + 0.5d)) / multi;

        }

        /// <summary>
        /// Busca el ContentControl llamado tag y le asigna value a la propiedad texto
        /// </summary>
        /// <param name="tag">Nombre del ContentControl</param>
        /// <param name="value">Valor a asignarle como texto al ContentControl tag</param>
        private void setControlValue(string tag, string value)
        {

            try
            {
                foreach (Microsoft.Office.Interop.Word.ContentControl item in Globals.ThisAddIn.Application.ActiveDocument.ContentControls)
                {
                    if (!string.IsNullOrEmpty(item.Tag))
                    {
                        if (item.Tag.ToLower().Equals(tag.ToLower()))
                        {
                            if (item.Tag.Equals("TH_PersonTypeCode")
                                || item.Tag.Equals("TH_ResidenceTypeCode")
                                || item.Tag.Equals("TH_CountryCode")
                                || item.Tag.Equals("SP_PersonTypeCode")
                                || item.Tag.Equals("SP_ResidenceTypeCode")
                                || item.Tag.Equals("SP_CountryCode")
                                || item.Tag.Equals("BP_PersonTypeCode")
                                || item.Tag.Equals("BP_ResidenceTypeCode")
                                || item.Tag.Equals("BP_CountryCode")
                                || item.Tag.Equals("IH_InvoiceDocumentType")
                                || item.Tag.Equals("IH_InvoiceClass")
                                || item.Tag.Equals("CORR_ReasonCode")
                                || item.Tag.Equals("CORR_ReasonDescription"))
                            {
                                /*si lo encontramos buscamos el valor correspondiente al texto seleccionado*/
                                foreach (ContentControlListEntry entry in item.DropdownListEntries)
                                {
                                    if (!string.IsNullOrEmpty(item.Tag))
                                    {
                                        if (entry.Value.ToLower().Equals(value.ToLower()))
                                        {
                                            value = entry.Text; break;
                                        }
                                    }

                                }
                            }
                            item.Range.Text = value; break;
                        }

                    }
                }
            }
            catch (Exception) { }
        }


        /// <summary>
        /// Método que calcula el valor de moneda de cambio
        /// </summary>
        /// <returns>Un String con el valor de la moneda</returns>
        private string getExchangeRate()
        {
            return String.Format(culturaOffice.NumberFormat, "{0:#,0.00}", double.Parse("1", culturaOffice.NumberFormat));
        }

        #endregion
    }
}
